//
//  CityDOCatchCrash.m
//  DeviceFingerPrintingSDK
//
//  Created by CityDo on 2019/3/15.
//  Copyright © 2019 CityDo. All rights reserved.
//

#import "CityDOCatchCrash.h"
#import "BSBacktraceLogger.h"
#import "HelperUtil.h"


//#ifdef DEBUG
//#define NSLog(FORMAT, ...) fprintf(stderr,"%s\n",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
//#else
//#define NSLog(...)
//#endif


@implementation CityDOCatchCrash

- (void)redirectNSLogToDocumentFolder
{
    //如果已经连接Xcode调试则不输出到文件
    //    if (isatty(STDOUT_FILENO)) {
    //        return;
    //    }
    
//    //判定如果是模拟器就不输出
//    UIDevice *device = [UIDevice currentDevice];
//    if ([[device model]hasSuffix:@"Simulator"]) {
//        return;
//    }
    
    //将NSLog打印信息保存到Document目录下的Log文件夹下
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL fileExists = [fileManager fileExistsAtPath:logDirectory];
    if (!fileExists) {
        NSError *error = nil;
        [fileManager createDirectoryAtPath:logDirectory withIntermediateDirectories:YES attributes:nil error:&error];
        if (error) {
            NSLog(@"error = %@",[error localizedDescription]);
        }
    }
    
//    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
//    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //每次启动都保存一个新的日志文件中
//    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
//    NSString *logFilePath = [logDirectory stringByAppendingFormat:@"/%@.log",dateStr];
    NSString *fileName = @"UncaughtException.txt";
    NSString *logFilePath = [logDirectory stringByAppendingFormat:@"/%@", fileName];
    NSLog(@"11111199999999");

    //将log文件输出到文件
    freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding], "a++", stdout);
    freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding], "a++", stderr);
    
    
//    NSString *fileNameOne = @"UncaughtExceptionAllStackInfo.log";@@@@
//    NSString *logFilePathOne = [logDirectory stringByAppendingFormat:@"/%@", fileNameOne];
//
//
//
//    freopen([logFilePathOne cStringUsingEncoding:NSUTF8StringEncoding], "a++", stdout);
//    freopen([logFilePathOne cStringUsingEncoding:NSUTF8StringEncoding], "a++", stderr);
//
    //捕获Object-C异常日志
    
    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}

void UncaughtExceptionHandler(NSException* exception)
{
    NSString *name = [exception name];
    NSString *reason = [exception reason];
    NSArray *symbols = [exception callStackSymbols];
    
    NSString * aa = [HelperUtil ExecutableUUID];
    
    NSDictionary * bb = [HelperUtil getUUIDDictionary];

    //异常发生时的调用栈
    NSMutableString *strSymbols = [[NSMutableString alloc]init];
    //将调用栈平成输出日志的字符串
    for (NSString *str in symbols) {
        [strSymbols appendString:str];
//        [strSymbols appendString:@"\r\n"];
    }
    
    
//    //三种获取方式
//    NSString * oneUUID = [HelperUtil executableUUID];
//    NSUUID  *twoUUID =  ExecutableUUID();
//    NSUUID *threeUUID =  [HelperUtil ExecutableUUID];
////    ,@"twoUUID":twoUUID.UUIDString,@"threeUUID":threeUUID.UUIDString
//    NSDictionary *dictUUID=@{@"oneUUID":oneUUID,@"twoUUID":twoUUID.UUIDString,@"threeUUID":threeUUID.UUIDString};
//    NSString *UUIDStringS = [HelperUtil dataTOjsonString:dictUUID];
//    UUIDStringS = [UUIDStringS stringByReplacingOccurrencesOfString:@"-" withString:@""];
//    [strSymbols appendString:UUIDStringS];
    

    
    //将crash日志保存到Document目录下的Log文件夹下
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0]stringByAppendingPathComponent:@"Log"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:logDirectory]) {
        NSError *error = nil;
        [fileManager createDirectoryAtPath:logDirectory withIntermediateDirectories:YES attributes:nil error:&error];
        if (error) {
            NSLog(@"error = %@",[error localizedDescription]);
        }
    }
    
//    NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"UncaughtException.txt"];
    NSString *allThreadInfologFilePath = [logDirectory stringByAppendingPathComponent:@"allThreads.txt"];
    NSString *mainThreadLogFilePath= [logDirectory stringByAppendingPathComponent:@"mainThread.txt"];
    NSString *currentThreadLogFilePath = [logDirectory stringByAppendingPathComponent:@"currentThread.txt"];


    
//    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
//    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
//    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
    
    NSDictionary *infoDictionary=[[NSBundle mainBundle] infoDictionary];
//    //     当前应用名称
//    NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
//    NSLog(@"当前应用名称：%@",appCurName);
//
    NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"];
//    NSLog(@"当前应用版本号码：%@",appCurVersionNum);
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    NSString *breakTime = [formatter stringFromDate:[NSDate date]];
    
    
    NSString * allThreads = [BSBacktraceLogger bs_backtraceOfAllThread];
    NSString * mainThread = [BSBacktraceLogger bs_backtraceOfMainThread];
    NSString * currentThread = [BSBacktraceLogger bs_backtraceOfCurrentThread];
    
    
    //全栈信息
    NSDictionary *dict =  @{@"breakTime":breakTime,@"name":name,@"excepName":reason,@"exception":strSymbols,@"appVersion":appCurVersionNum,@"uuid":aa};
    
//    NSDictionary *dict = @{@"breakTime":breakTime,@"name":name,@"excepName":reason,@"exception":strSymbols,@"appVersion":appCurVersionNum,@"uuid":aa};
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:dict forKey:@"dict"];
    [defaults synchronize];

    
    NSString *crashStringOne = [ dict descriptionWithLocale:nil];

//    //出错栈
//    NSString *crashString = [NSString stringWithFormat:@"[Uncaught Exception]Name:%@,Reason:%@[Fe Symbols Start]%@[Fe Symbols End]",name,reason,strSymbols];
//    
//    //把错误日志写到文件中
//    if (![fileManager fileExistsAtPath:logFilePath]) {
//        [crashString writeToFile:logFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
//    }else{
//        NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:logFilePath];
//        [outFile seekToEndOfFile];
//        [outFile writeData:[crashString dataUsingEncoding:NSUTF8StringEncoding]];
//        [outFile closeFile];
//    }
    
    //把全栈信息写到文件中
    if (![fileManager fileExistsAtPath:allThreadInfologFilePath]) {
        [allThreads writeToFile:allThreadInfologFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }else{
        NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:allThreadInfologFilePath];
        [outFile seekToEndOfFile];
        [outFile writeData:[allThreads dataUsingEncoding:NSUTF8StringEncoding]];
        [outFile closeFile];
    }
    
    //把全栈信息写到文件中
    if (![fileManager fileExistsAtPath:mainThreadLogFilePath]) {
        [mainThread writeToFile:mainThreadLogFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }else{
        NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:mainThreadLogFilePath];
        [outFile seekToEndOfFile];
        [outFile writeData:[mainThread dataUsingEncoding:NSUTF8StringEncoding]];
        [outFile closeFile];
    }
    
    //把全栈信息写到文件中
    if (![fileManager fileExistsAtPath:currentThreadLogFilePath]) {
        [currentThread writeToFile:currentThreadLogFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    }else{
        NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:currentThreadLogFilePath];
        [outFile seekToEndOfFile];
        [outFile writeData:[mainThread dataUsingEncoding:NSUTF8StringEncoding]];
        [outFile closeFile];
    }

//    //把错误日志发送到邮箱
//    NSString *urlStr = [NSString stringWithFormat:@"mailto://(此处为邮箱地址)?subject=bug&body=感谢您的配合错误详情:%@",crashString];
//    NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//    [[UIApplication sharedApplication]openURL:url];
}


@end
